using Framework.Bundle;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace Framework
{
    public class AssetBundleEditor : EditorWindow
    {
        private BundleConfig m_Config = null;
        private Vector2 scrollViewPos = Vector2.zero;
        private SerializedObject serializedObject;
        private ReorderableList orderableList;
        private int startCleanup = 0;
        private int startBuild = 0;
        private int startAnalyze = 0;
        private bool _create;
        public static void CreateWindow()
        {
            AssetBundleEditor bundleBuilder = GetWindow<AssetBundleEditor>(true, "资源包配置", true);
            bundleBuilder.minSize = new Vector2(AssetPackDrawer.Width, 500);
            bundleBuilder.maxSize = new Vector2(AssetPackDrawer.Width, 800);
        }

        private void OnEnable()
        {
            _create = true;
            CheckSameConfig();

            Array buildTargets = Enum.GetValues(typeof(BuildTarget));
            foreach (BuildTarget buildTarget in buildTargets)
            {
                var targetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
                if (!BuildPipeline.IsBuildTargetSupported(targetGroup, buildTarget))
                {
                    if (m_Config != null)
                    {
                        if (m_Config.BuildTarget == buildTarget)
                        {
                            m_Config.BuildTarget = BuildTarget.NoTarget;
                            break;
                        }
                    }
                }
            }
            if (m_Config != null)
            {
                if (m_Config.BuildTarget == BuildTarget.NoTarget)
                {
                    m_Config.BuildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
                }
            }
        }
        private void CheckSameConfig()
        {
            //BundleConfig.SetDefaultConfigFile("AndroidBundleConfig.asset");
            m_Config = BundleConfig.GetInstance(true);
            if (m_Config == null) return;
            if (string.IsNullOrEmpty(m_Config.BundleExtension))
            {
                EditorUtility.DisplayDialog("警告", "资源后缀名不能为空", "确定", "知道了");
            }
            Dictionary<string, bool> configMap = new Dictionary<string, bool>();
            foreach (var packConfig in m_Config.BundleItems)
            {
                if (packConfig == null)
                {
                    continue;
                }
                var key = packConfig.GetName();
                if (configMap.ContainsKey(key))
                {
                    EditorUtility.DisplayDialog("警告", string.Format("存在相同的配 {0}", key), "确定", "知道了");
                    return;
                }
                configMap.Add(key, true);
            }
        }
        private void OnDisable()
        {
            CheckSameConfig();
            m_Config?.Save();
        }
        private void OnInspectorUpdate()
        {
            if (startBuild > 0)
            {
                startBuild--;
                if (startBuild < 1)
                {
                    var p = new BuildPipline();
                    p.Execute();
                }

            }
            if (startAnalyze > 0)
            {
                startAnalyze--;
                if (startAnalyze < 1)
                {
                    Type log = typeof(EditorWindow).Assembly.GetType("UnityEditor.LogEntries");
                    if (log != null)
                    {
                        var clearMethod = log.GetMethod("Clear");
                        if (clearMethod != null)
                        {
                            clearMethod.Invoke(null, null);
                        }
                    }
                    var p = new BuildPipline();
                    p.Analyze();
                }
            }
            if (startCleanup > 0)
            {
                startCleanup--;
                if (startCleanup < 1)
                {
                    ToolsMenu.InternalCleanFolder(m_Config.GetBuildCachePath());
                    //var builder = new AssetBundleBuilder();
                    //builder.CleanupCache();
                }
            }
        }
        private void OnGUI()
        {
            if(_create)
            {
                _create=false;
                m_Config = BundleConfig.GetInstance();
                return;
            }
            if (m_Config == null)
            {
                //m_Config = BundleConfig.GetInstance();
                return;
            }
            if (serializedObject == null && m_Config != null)
            {
                serializedObject = new SerializedObject(m_Config);
            }

            serializedObject.Update();

            try
            {
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
                float minWidth = 80f;
                float minHeight = 60f;


                if (GUILayout.Button("构建", GUILayout.MinWidth(minWidth), GUILayout.Height(minHeight)))
                {
                    if (EditorUtility.DisplayDialog("警告", "确定要执行耗时操作吗?", "确定", "取消"))
                    {
                        startBuild = 5;
                    }
                }
                GUILayout.Space(20);
                if (GUILayout.Button("导出", GUILayout.MinWidth(minWidth), GUILayout.Height(minHeight)))
                {
                    var p = new BuildPipline();
                    p.Export();
                }
                GUILayout.Space(20);
                if (GUILayout.Button("打开目录", GUILayout.MinWidth(minWidth), GUILayout.Height(minHeight)))
                {
                    var targetPath = m_Config.GetOutputRootPath();
                    if (!Directory.Exists(targetPath)) return;
                    ToolsMenu.OpenFolder(targetPath);
                }
                GUILayout.Space(20);
                if (GUILayout.Button("分析", GUILayout.MinWidth(minWidth), GUILayout.Height(minHeight)))
                {
                    if (EditorUtility.DisplayDialog("警告", "分析当前配制是否合理", "确定", "取消"))
                    {
                        startAnalyze = 5;
                    }
                }
                EditorGUI.EndDisabledGroup();
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
                DrawOutputPathInfo();
                GUILayout.Space(5f);
                DrawBatchBuild();
                serializedObject.ApplyModifiedProperties();

            }
            catch (System.Exception)
            {

            }



        }
        Vector2 scrollPos;//滚动窗口需要
        private void DrawBatchBuild()
        {
            EditorGUILayout.LabelField("配制项目", EditorStyles.boldLabel);
            EditorGUILayout.BeginVertical("box");
            {
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                var propertys = AssetPackDrawer.GetPropertyList();
                for (var i = 0; i < propertys.Count; i++)
                {
                    var p = propertys[i];
                    GUILayout.Label(p.Label, GUILayout.Width(p.Width * AssetPackDrawer.Width));
                }
                GUILayout.EndHorizontal();

                scrollViewPos = GUILayout.BeginScrollView(scrollViewPos, false, false);
                drawReorderablePackConfig();
                GUILayout.EndScrollView();
            }
            EditorGUILayout.EndVertical();
        }

        private void drawReorderablePackConfig()
        {
            if (orderableList == null)
            {
                SerializedProperty list = serializedObject.FindProperty("BundleItems");
                orderableList = new ReorderableList(serializedObject, list, true, false, true, true);
                orderableList.elementHeight = 22;
                orderableList.drawElementCallback = (rect, index, isActive, isFocused) =>
                {
                    var element = list.GetArrayElementAtIndex(index);
                    rect.height = 20f;
                    rect.y = rect.y + 2;
                    EditorGUI.PropertyField(rect, element, GUIContent.none);
                };
            }
            if (orderableList != null)
            {
                orderableList.DoLayoutList();
            }
        }


        private void DrawOutputPathInfo()
        {
            GUILayout.Space(5f);
            EditorGUILayout.LabelField("打包配制", EditorStyles.boldLabel);
            EditorGUILayout.BeginVertical("box");
            {

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("平台:", GUILayout.Width(30f));

                    m_Config.BuildTarget = (BuildTarget)EditorGUILayout.EnumPopup(m_Config.BuildTarget, GUILayout.MinWidth(100), GUILayout.MaxWidth(200));
                    if (GUILayout.Button("切换到当前平台", GUILayout.MinWidth(80), GUILayout.MaxWidth(100)))
                    {
                        m_Config.BuildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
                    }
                    if (GUILayout.Button("清理缓存", GUILayout.MinWidth(80), GUILayout.MaxWidth(100)))
                    {
                        if (EditorUtility.DisplayDialog("警告", "清缓存后构建时间会变长!", "确定", "取消"))
                        {
                            startCleanup = 1;
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();

                /*
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("输出:", GUILayout.Width(30f));
                m_Config.OutputDirectory = EditorGUILayout.TextField(m_Config.OutputDirectory);
                if (GUILayout.Button("选择目录", GUILayout.Width(80f)))
                {
                    BrowseOutputDirectory();
                }
                EditorGUILayout.EndHorizontal();
                */

            }
            EditorGUILayout.EndVertical();

        }
        private void BrowseOutputDirectory()
        {
            string directory = EditorUtility.OpenFolderPanel("Select Output Directory", m_Config.OutputDirectory, string.Empty);
            if (!string.IsNullOrEmpty(directory))
            {
                m_Config.OutputDirectory = directory + "/";
            }
        }

    }
    [CustomPropertyDrawer(typeof(BundleItemData))]
    public class AssetPackDrawer : PropertyDrawer
    {
        public const float Width = 600f;
        public const float Gap = 10f;
        private static List<AssetPackPropertyUI> propertys;
        public static List<AssetPackPropertyUI> GetPropertyList()
        {
            if (propertys != null)
            {
                return propertys;
            }
            propertys = new List<AssetPackPropertyUI>() {
                new AssetPackPropertyUI(){Name="Source" ,Label="文件目录",Width=0.2f},
                new AssetPackPropertyUI(){Name="AssetType" ,Label="资源类型",Width=0.2f},
                new AssetPackPropertyUI(){Name="PackType" ,Label="分包类型",Width=0.2f},
                // new AssetPackPropertyUI(){Name="Encrypt" ,Label="是否加密",Width=0.1f},
            };
            var p = 0f;
            var len = propertys.Count;
            while (len-- > 0)
            {
                p += propertys[len].Width;
            }
            len = propertys.Count;
            for (var i = 0; i < len; i++)
            {
                var item = propertys[i];
                item.Width /= p;
            }
            return propertys;
        }
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var w = position.width - Gap - 10f;
            var list = GetPropertyList();
            var len = list.Count;
            var xoffset = 0f;
            for (var i = 0; i < len; i++)
            {
                var item = list[i];
                drawItem(position, property, item.Name, xoffset, item.Width * w);
                xoffset += item.Width * w + Gap;
            }

        }
        private void drawItem(Rect position, SerializedProperty property, string name, float offset, float width)
        {
            var rect = new Rect(position);
            rect.x = position.x + offset;
            rect.height = position.height;
            SerializedProperty item = property.FindPropertyRelative(name);
            rect.width = width;
            EditorGUI.PropertyField(rect, item, GUIContent.none);
        }
    }
    public class AssetPackPropertyUI
    {
        public string Name;
        public string Label;
        public float Width;
    }
}
